"use strict";
// const webpack = require("webpack");
// const path = require("path-browserify")
// const hp2 = require("htmlparser2");

const HtmlWebpackPlugin = require("html-webpack-plugin");

/**
 * @typedef {object} HtmlAddonOption
 * @property {{(s?: unknown):string}=} injectHeadFn 注入head标签内的内容
 * @property {{(s?: unknown):string}=} injectBodyFn 注入body标签内的内容
 */

/**
 * @typedef {import('webpack').WebpackPluginInstance} WebpackPluginInstance
 * @implements {WebpackPluginInstance}
 */
class HtmlAddonPlugin {
  /**
   * @private
   * @type {HtmlAddonOption}
   */
  options = {};

  static PLUGIN_NAME = "HtmlAddonPlugin";

  /**
   * @param {HtmlAddonOption} options
   */
  constructor(options) {
    this.options = options;
  }

  /**
   * @param {import('webpack').Compiler} compiler
   */
  apply(compiler) {
    compiler.hooks.compilation.tap(
      HtmlAddonPlugin.PLUGIN_NAME,
      (compilation) => {
        // Static Plugin interface |compilation |HOOK NAME | register listener
        HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tapAsync(
          HtmlAddonPlugin.PLUGIN_NAME, // <-- Set a meaningful name here for stacktraces
          (data, cb) => {
            // console.log("process html: ", data.outputName)
            // is HTML main page/
            if (/<!DOCTYPE\shtml>/.test(data.html)) {
              let { html } = data;
              if (this.options.injectHeadFn) {
                html = html.replace(
                  /<\/head>/,
                  `${this.options.injectHeadFn(html) || ""}</head>`,
                );
              }
              if (this.options.injectBodyFn) {
                html = html.replace(
                  /<\/body>/,
                  `${this.options.injectBodyFn(html) || ""}</body>`,
                );
              }

              cb(null, {
                ...data,
                html,
              });
            } else {
              cb(null, data);
            }
          },
        );
      },
    );
  }
}

module.exports = { HtmlAddonPlugin };
